type EventHandler = (data?: any) => void;

class EventBus {
  private events: Map<string, EventHandler[]>;

  constructor() {
    this.events = new Map();
  }

  /**
   * Register an event handler.
   * @param eventName The name of the event.
   * @param handler The handler function.
   */
  on(eventName: string, handler: EventHandler): void {
    if (!this.events.has(eventName)) {
      this.events.set(eventName, []);
    }
    this.events.get(eventName)!.push(handler);
  }

  /**
   * Unregister an event handler.
   * @param eventName The name of the event.
   * @param handler The handler function to remove.
   */
  off(eventName: string, handler: EventHandler): void {
    const handlers = this.events.get(eventName);
    if (handlers) {
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
      }
    }
  }

  /**
   * Emit an event.
   * @param eventName The name of the event.
   * @param data The data to pass to the handlers.
   */
  emit(eventName: string, data?: any): void {
    const handlers = this.events.get(eventName);
    if (handlers) {
      handlers.forEach((handler) => handler(data));
    }
  }
}

// Export a singleton instance
export const eventBus = new EventBus();

/**
 * Defines event names used in the application.
 */
export const EventKeys = {
  NOTE_SAVED: "note:saved",
  PAGE_SHOW: "page:show",
};
